package sc.senai.br.avaliacao;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public final class JuizImpl extends UnicastRemoteObject implements Juiz {
    private final String campeonato;
    private final HashMap<String, Integer> vencedores;
    private final ComiteImpl comiteImpl;
    private String vencedorCampeonato = "";
    private int rodadas = 0;
    private final int regraVitoria;

    public JuizImpl(ComiteImpl comiteImpl, String campeonato, int regraVitoria) throws RemoteException {
        if (regraVitoria < 1) {
            throw new RemoteException("Regra de vitória < 1.");
        }
        this.regraVitoria = regraVitoria;
        this.campeonato = campeonato;
        this.vencedores = new HashMap<String, Integer>();
        this.comiteImpl = comiteImpl;
    }

    public String apuraResultado(Map<String, Jogadas> jogadas) throws RemoteException {
        if (!this.vencedorCampeonato.isEmpty()) {
            throw new RemoteException(String.format("Campeonato %s encerrado com o vencedor: %s", new Object[] { this.campeonato, this.vencedorCampeonato }));
        }
        this.rodadas += 1;
        HashSet<Jogadas> escolhas = new HashSet<Jogadas>(jogadas.values());
        Jogadas vencedora = null;
        for (Jogadas j1 : escolhas) {
            for (Jogadas j2 : escolhas) {
                if (!j1.disputa(j2)) {
                    break;
                }
                vencedora = j1;
            }
            if (vencedora != null) {
                break;
            }
        }
        String vencedor = "";
        if (vencedora != null) {
            for (Map.Entry<String, Jogadas> entry : jogadas.entrySet()) {
                if (entry.getValue() == vencedora) {
                    if (vencedor.isEmpty()) {
                        vencedor = (String) entry.getKey();
                    }
                    else {
                        vencedor = "";
                        break;
                    }
                }
            }
        }
        if (!vencedor.isEmpty()) {
            String nomeVencedor = this.comiteImpl.getNomeRegistro(vencedor);
            if (nomeVencedor == null) {
                throw new RemoteException("Jogador " + vencedor + " não está registrado no Comitê!");
            }
            vencedor = nomeVencedor;
            int vitorias = this.vencedores.containsKey(vencedor) ? ((Integer) this.vencedores.get(vencedor)).intValue() + 1 : 1;
            this.vencedores.put(vencedor, Integer.valueOf(vitorias));
            if (vitorias == this.regraVitoria) {
                this.vencedorCampeonato = vencedor;
            }
        }
        System.out.println(String.format("Campeonato %s - Rodada #%02d - Nr Jogadores %d - %s", new Object[] { this.campeonato, Integer.valueOf(this.rodadas), Integer.valueOf(jogadas.size()), vencedor.isEmpty() ? "Empate" : vencedor }));
        if (!this.vencedorCampeonato.isEmpty()) {
            System.out.println(String.format("Campeonato %s encerrado - Vencedor %s", new Object[] { this.campeonato, this.vencedorCampeonato }));
        }
        return vencedor;
    }

    public String getVencedorCampeonato() throws RemoteException {
        return this.vencedorCampeonato;
    }

    public boolean hasVencedorCampeonato() throws RemoteException {
        return !this.vencedorCampeonato.isEmpty();
    }
}